{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from math import exp\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# data\n",
    "def create_data():\n",
    "    iris = load_iris()\n",
    "    df = pd.DataFrame(iris.data, columns=iris.feature_names)\n",
    "    df['label'] = iris.target\n",
    "    df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']\n",
    "    data = np.array(df.iloc[:100, [0,1,-1]])\n",
    "    # print(data)\n",
    "    return data[:,:2], data[:,-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X, y = create_data()\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 2)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100,)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(70, 2) (30, 2) (70,) (30,)\n"
     ]
    }
   ],
   "source": [
    "print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class LogisticReressionClassifier:\n",
    "    def __init__(self, max_iter=200, learning_rate=0.01):\n",
    "        self.max_iter = max_iter\n",
    "        self.learning_rate = learning_rate\n",
    "        \n",
    "    def sigmoid(self, x):\n",
    "        return 1 / (1 + exp(-x))\n",
    "\n",
    "    def data_matrix(self, X):\n",
    "        data_mat = []\n",
    "        for d in X:\n",
    "            data_mat.append([1.0, *d])\n",
    "        return data_mat\n",
    "\n",
    "    def fit(self, X, y):\n",
    "        # label = np.mat(y)\n",
    "        data_mat = self.data_matrix(X) # m*n\n",
    "        self.weights = np.zeros((len(data_mat[0]),1), dtype=np.float32)\n",
    "\n",
    "        for iter_ in range(self.max_iter):\n",
    "            for i in range(len(X)):\n",
    "                result = self.sigmoid(np.dot(data_mat[i], self.weights))\n",
    "                error = y[i] - result \n",
    "                self.weights += self.learning_rate * error * np.transpose([data_mat[i]])\n",
    "        print('LogisticRegression Model(learning_rate={},max_iter={})'.format(self.learning_rate, self.max_iter))\n",
    "\n",
    "    # def f(self, x):\n",
    "    #     return -(self.weights[0] + self.weights[1] * x) / self.weights[2]\n",
    "\n",
    "    def score(self, X_test, y_test):\n",
    "        right = 0\n",
    "        X_test = self.data_matrix(X_test)\n",
    "        for x, y in zip(X_test, y_test):\n",
    "            result = np.dot(x, self.weights)\n",
    "            if (result > 0 and y == 1) or (result < 0 and y == 0):\n",
    "                right += 1\n",
    "        return right / len(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LogisticRegression Model(learning_rate=0.01,max_iter=200)\n"
     ]
    }
   ],
   "source": [
    "lr_clf = LogisticReressionClassifier()\n",
    "lr_clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lr_clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x11b98deb8>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8VPW9//HXhySQsC8BgYSQkCAqiyjILgS9iiIutWih\n2l6XSkG8ba+tVu/P21bbe6u1vbX+2ERtqRvWWsWlqFclEQFBA7IJKpMESMIWwIQtgWTyvX/MoDEm\n5JCcmfOdk8/z8cgjmTOHM9/vHP3k5Jz3+YwYY1BKKeUvrbwegFJKKfdpcVdKKR/S4q6UUj6kxV0p\npXxIi7tSSvmQFnellPIhLe5KKeVDWtyVUsqHtLgrpZQPxXv1wsnJySY9Pd2rl1dKqZi0du3a/caY\n7o2t57i4i0gckAeUGGOm1HkuG3gFKAwveskY88Cptpeenk5eXp7Tl1dKKQWIyA4n653OkfuPga1A\nxwaef79u0VdKKeUNR+fcRSQVuAJ4IrLDUUop5QanF1QfAe4Gak6xzhgR2Sgib4jIwPpWEJEZIpIn\nInmlpaWnO1allFIONXpaRkSmAPuMMWvD59brsw5IM8YcEZHJwBKgf92VjDELgYUAw4cP117DSilP\nVFVVUVxcTGVlpddDaVBiYiKpqakkJCQ06d87Oec+FrgqXLQTgY4i8owx5saTKxhjDtX6eamIzBOR\nZGPM/iaNSimlIqi4uJgOHTqQnp6OiHg9nG8wxnDgwAGKi4vJyMho0jYaPS1jjLnXGJNqjEkHpgHL\nahd2ABHpKeF3SERGhLd7oEkjUkqpCKusrKRbt25WFnYAEaFbt27N+suiyTl3EZkJYIxZAEwFZolI\nNVABTDP6EU9KKYvZWthPau74Tqu4G2NygdzwzwtqLZ8DzGnWSJTykSUfl/DwW5+xq6yC3p2TuGvS\nAK45L8XrYakWRNsPKOWyJR+XcO9Lmygpq8AAJWUV3PvSJpZ8XOL10JRF3nzzTQYMGEBWVhYPPvig\n69vX4q6Uyx5+6zMqqoJfW1ZRFeThtz7zaETKNsFgkNmzZ/PGG2+wZcsWFi9ezJYtW1x9Dc96yyjl\nV7vKKk5rubKf26fZPvzwQ7KysujXrx8A06ZN45VXXuGcc85xa8h65K6U23p3Tjqt5cpukTjNVlJS\nQp8+fb58nJqaSkmJu6fttLgr5bK7Jg0gKSHua8uSEuK4a9IAj0akmiNWT7PpaRmlXHbyz3VNy/hD\nJE6zpaSkUFRU9OXj4uJiUlLc/e9Di7tSEXDNeSlazH2id+ckSuop5M05zXbBBRewbds2CgsLSUlJ\n4fnnn+e5555rzjC/QU/LKKXUKUTiNFt8fDxz5sxh0qRJnH322Vx//fUMHFhvv8Wmv4arW1NKKZ+J\n1Gm2yZMnM3nyZDeGWC8t7kop1YhYPM2mp2WUUsqHtLgrpZQPaXFXSikf0uKulFI+pMVdKaV8SIu7\nUoT6h4x9cBkZ9/yTsQ8u0/a8KuJuueUWevTowaBBgyKyfS3uqsXT/uvKCzfddBNvvvlmxLavxV21\neLHaGEpF0cYX4I+D4FedQ983vtDsTY4fP56uXbu6MLj66U1MqsXT/uvqlDa+AK/9CKrC/z2UF4Ue\nAwy53rtxNUKP3FWLp/3X1Sm9+8BXhf2kqorQcotpcVctnvZfV6dUXnx6yy2hp2VUi6f919UpdUoN\nnYqpb7nFtLgrRWw2hlJRcvEvvn7OHSAhKbS8GaZPn05ubi779+8nNTWV+++/n1tvvbWZg/2KFnel\nlDqVkxdN330gdCqmU2qosDfzYurixYtdGFzDtLgrq7j9KfNKuWLI9VYnY+qjxV1Z4+TNRCcz5ydv\nJgK0wCt1mjQto6yhNxOpaDLGeD2EU2ru+LS4K2vozUQqWhITEzlw4IC1Bd4Yw4EDB0hMTGzyNvS0\njLJGJD5lXqn6pKamUlxcTGlpqddDaVBiYiKpqU2PW2pxV9a4a9KAr51zB72ZSEVGQkICGRkZXg8j\norS4K2vozURKucdxcReROCAPKDHGTKnznAB/AiYDx4CbjDHr3Byoahn0ZiLlRxuKyuiQGE+/7u2j\n9pqnc+T+Y2Ar0LGe5y4H+oe/RgLzw9+VUqeguX7/MsawuuAgc3MCrAjsZ+qwVH5/3blRe31HxV1E\nUoErgP8C7qxnlauBp0zo0vNqEeksIr2MMbvdG6pS/qK5fn8yxpDz2T7mLAuwbmcZye3bcO/lZ3HD\nqL5RHYfTI/dHgLuBDg08nwLU7qxTHF6mxV2pBpwq16/FPfYEawxvbN7N3Jx8tu4+RErnJH599UCu\nG96HxDpdR6Oh0eIuIlOAfcaYtSKS3ZwXE5EZwAyAtLS05mxKqZinuX5/OFFdw5L1JSzIzadg/1H6\ndW/H7687l6uH9iYhzrtbiZwcuY8FrhKRyUAi0FFEnjHG3FhrnRKgT63HqeFlX2OMWQgsBBg+fLid\ndw8oFSWa649tlVVB/vZREY+9l8+u8krO6dWReTecz6SBPYlrJV4Pr/Hiboy5F7gXIHzk/rM6hR3g\nVeAOEXme0IXUcj3frtSpaa4/Nh2urOKZ1Tt5ckUB+4+cYHjfLvzXtYPJPrM7oeCgHZqccxeRmQDG\nmAXAUkIxyAChKOTNroxOKR/TXH9sOXj0BItWFrJo1XYOVVZzYf9k7piYxYiMrlYV9ZPEq94Kw4cP\nN3l5eZ68tlJKObX3UCWPLy/g2TU7qagKMmngGcyemMWQ1M6ejEdE1hpjhje2nt6hqnztviWbWLym\niKAxxIkwfWQffnPNYK+HpWLAzgPHWLA8nxfzigkaw1Xn9mZWdiZnntFQaNAuWtyVb923ZBPPrN75\n5eOgMV8+1gKvGrJt72Hm5ebz6oZdxIkwdXgqM8dnktatrddDOy1a3JVvLV5Tz4cah5drcVd1bSwu\nY25OgLc+2UtSQhw3j0nntvH9OKNj09vuekmLu/KtYAPXkxparloeYwwfFh5kTk6A97ftp2NiPD+6\nKIubxmbQtV1rr4fXLFrclW/FidRbyOMsTDao6DLGkPt5KXOXBcjb8QXJ7Vvz88vO4sZRaXRITPB6\neK7Q4q58a/rIPl875157uWqZgjWGtz7Zw9ycAJ/sOkTvToncf9VAvnOBNy0CIkmLu/Ktk+fVNS2j\nqoI1vLJ+F/NyAxSUHiUjuR2/mzqEa4am0Dren582qjl3pZRvVVYF+XteEQveK6CkrIKze3Vk9sRM\nLh/Uy4oWAU2hOXdllRse/4CV+Qe/fDw2syvP3jbawxFFlvZp99aR49U8s3oHT7xfyP4jxzk/rTO/\nvmYgEwf0sPJu0kjQ4q4irm5hB1iZf5AbHv/AlwVe+7R754ujJ1i0ajuLVm2nvKKKcVnJzJ54HqP6\n2dkiIJK0uKuIq1vYG1se67RPe/TtO1TJEysKeWb1Do6dCHLJOaEWAUP7eNMiwAZa3JVymfZpj56i\ng8d4bHk+L+QVUx2s4cpze3N7dhYDesZGi4BI0uKulMu0T3vkBfaFWgS8sn4XrQSmDktl5oRM+nZr\n5/XQrKHFXUXc2Myu9Z6CGZvZ1YPRRJ72aY+czSXlzM0J8OYne2gT34p/HZ3ObeMz6NVJf3HWpcVd\nRdyzt41uUWkZ7dPuvg8LDzI3J8B7n5fSITGe2dlZ3Dw2nW7t23g9NGtpzl0pZSVjDO99Xsq8nHw+\n3H6Qbu1ac8u4DL43ui8dfdIioCk0566s4nbu2+n2NG8ee2pOtgjIDbC55BC9OiXyyyvPYdoFaSS1\n9leLgEjS4q4izu3ct9Ptad48tlQFa3h1/S7mv5dPYN8R0ru15aFvD+Zb56X6tkVAJOk7piLuVLnv\nSG7P7ddVkVFZFeTp1TuY+Ptcfvr3DcS3Eh6dfh7v/jSb71yQpoW9ifTIXUWc27lvp9vTvLndjh6v\n5rk1O3n8/QL2HT7O0D6d+dWVA7n47JbTIiCStLiriHM79+10e5o3t1PZsRP8ddUO/rKqkLJjVYzJ\n7MYj3xnK6MxuWtRdpH/vqIi7a9IAkur0ym5O7tvp9tx+XdU8+w5X8ts3tjL2wWX88Z3PGd63Cy/d\nPobnbhvFmKxkLewu0yN3FXFu576dbk/z5nYo/uIYC5cX8LePiqgK1nDFkN7cnp3J2b06ej00X9Oc\nu1IqIvJLjzA/N58lH5cgAteel8rM7EwykrVFQHNozt0nbM9p2z4+FX2bS8qZn5vP0s27aRPfihtH\n9WXG+H56rSPKtLhbzPactu3jU9GVtz3UIiDns1I6tIln1oRMbhmXQbK2CPCEFneL2d4X3Pbxqcgz\nxvD+tv3MzQmwpvAgXdu15meXnsn3RqfTKanltgiwgRZ3i9me07Z9fCpyamoM/7tlL/NyA2wsLqdn\nx0T+c8o5TB/Rh7attazYQPeCxWzPads+PuW+6mANr2/czbzcAJ/vPUJa17b89trBXHt+Cm3ite+L\nTTTnbjHbc9q2j0+553h1kOfW7OSiP7zHT/62HoA/TRvKsp9OYPqINC3sFtIjd4vZntO2fXyq+Y6d\n+KpFwN5Dxzk3tRP3XTGMfzn7DFq10puObNZozl1EEoHlQBtCvwxeNMb8ss462cArQGF40UvGmAdO\ntV3NuStlr/KKKp5atZ0/ryzki2NVjO7XjdkTsxibpS0CvOZmzv04cJEx5oiIJAArROQNY8zqOuu9\nb4yZ0pTBqth135JNLF5TRNAY4kSYPrIPv7lmcJPX8yo3r3n9kNLDx/nzykKe/mAHR45Xc/FZPbh9\nYhbD+nbxemjqNDVa3E3o0P5I+GFC+Mub21qVVe5bsolnVu/88nHQmC8f1y7cTtfzKjevef3QnB9f\nXsDiD3dyIljDFYN7cXt2Fuf01hYBscrRBVURiROR9cA+4G1jzJp6VhsjIhtF5A0RGejqKJWVFq8p\ncrTc6Xpe9V9vyX3fC0qPcPeLG5jwuxyeWb2Dq4f25t07JzDnu+drYY9xji6oGmOCwFAR6Qy8LCKD\njDGba62yDkgLn7qZDCwB+tfdjojMAGYApKWlNXvwylvBBq7X1F3udD2vcvMtMa+/Zdch5uUGWLpp\nNwlxrbhhZBozJmSSojFW3zittIwxpkxEcoDLgM21lh+q9fNSEZknIsnGmP11/v1CYCGELqg2a+TK\nc3Ei9RbuuDoX3Jyu51VuviXl9dfu+IJ5OQHe/XQf7dvEM2N8JreOy6B7B20R4DeNnpYRke7hI3ZE\nJAm4BPi0zjo9JXwJXURGhLd7wP3hKptMH9nH0XKn63mVm/d7Xt8Yw8rAfqYvXM23569i7c4vuPOS\nM1n584u45/KztLD7lJMj917AX0UkjlDRfsEY87qIzAQwxiwApgKzRKQaqACmGa96CauoOXkxtLEU\njNP1vMrN+zWvX1NjePfTfczJCbChqIweHdpw3xVnM31EGu3a6C0ufqf93JXymepgDf/ctJt5Ofl8\ntvcwfbomMXNCJlOHpeqdpD6g/dx9wu38tdO8udvbczoP2+drs+PVQV5+9RXmrz3MjmAy/eP28sfR\nnbhyyuXEx2mnkZZGi7vF3M5fO82bu709p/Owfb62Onaimuc/LGLhu5vZU9GGwVLCgoSnuLTVWlpt\nToSMIAy53uthqijTX+cWczt/7TRv7vb2nM7D9vnapryiirk5AcY9lMMDr2+hb3UhTyX8lldb38dl\ncXm0EgNVFfDuKTuBKJ/SI3eLuZ2/dpo3d3t7Tudh+3xtceBIqEXAU6t2cPh4NRMHdGf2xCyGL7qB\nem8eLy+O+hiV97S4W8zt/LXTvLnb23M6D9vn67Xd5RUsDLcIOF5dw+RBvZiVncmglE6hFTqlQnk9\nf5V0So3uQJUV9LSMxdzOXzvNm7u9PafzsH2+Xtm+/yj3/GMj43+Xw9Mf7GDKkN68/e8TmHvD+V8V\ndoCLfwEJdX4RJiSFlqsWR4/cLeZ2/tpp3tzt7Tmdh+3zjbZP9xxiXk4+r2/cRXxcK6aPSGPG+H6k\ndmlb/z84edH03QdCp2I6pYYKu15MbZE0566UZdYXlTFnWYB3tu6lXes4bhzdl1vHZdCjQ6LXQ1MW\n0Jy7igqv8ut+Y4zhg4IDzM0JsDJwgE5JCfzkX/pz05h0Ordt7fXwGrfxBf2LwTJa3FWTeZVf9xNj\nDMvCLQI+3llG9w5t+I/JZ/HdkX1pHystAja+AK/9KBS7hNBF3dd+FPpZC7xnYuS/HmWjU+XSaxdt\np+u1JMEaw9JNu5mbE+DTPYdJ7ZLEr68ZxHXDUklMiLEWAe8+8FVhP+lkvl6Lu2e0uKsm8yq/HstO\nVNew5OMS5r+XT+H+o2R2b8cfrjuXq4b2JiFWWwQ0lKPXfL2ntLirJvMqvx6LKk4E+dtHO1m4vIBd\n5ZUMSunI/BvOZ9LAnrRqFZu5+y9pvt5KMXqooGzgVX49lhyqrGJeboBxDy3jV69tIbVLWxbdfAGv\n3TGOywf3iv3CDpqvt5Qeuasm8yq/HgsOHj3BX1YWsmjVdg5XVjPhzFCLgBEZXb0emvs0X28lzbkr\n5aI95ZU8/n4Bz63ZSWV1kMsG9uT27CwGp3Zq/B8r5YDm3D3idp7b6fa86luu+fWQHQeOsuC9Av6x\ntpigMVw9tDe3Z2eS1aODOy/gpxy5n+bihEfz1eLuIrfz3E6351Xfcs2vw+d7DzMvJ8CrG0ItAq6/\nIJUfjs+kT9cGWgQ0hZ9y5H6aixMezlcvqLrI7X7kTrfnVd9yt+cbSzYUlTHjqTwu/eNy/nfLXn5w\nYT9W3D2R31wz2N3CDqfOkccaP83FCQ/nq0fuLnI7z+10e171LW9p+XVjDGsKDzI3J8D72/bTKSmB\nH18cahHQpV0EWwT4KUfup7k44eF8tbi7yO08t9PtedW3vKXk140x5H5WypycAGt3fEFy+zbce/lZ\n3DAqSi0C/JQj99NcnPBwvnpaxkVu57mdbs+rvuV+z68Hawz/3LibKx5dwc2LPmJPeSW/vnogK34+\nkR9OyIxe7xc/5cj9NBcnPJyvHrm7yO08t9PtedW33K/59argVy0CCkqP0q97O35/3blc7VWLAD/l\nyP00Fyc8nK/m3JUKq6wK8kJeEY+9V0BJWQXn9OrIHRdlMWlgT+L8cCep8gXNufuEV7n5Gx7/gJX5\nB798PDazK8/eNrrJr2uzw5VVPLtmJ0+8X8j+I8cZ3rcLv/nWILLP7I7E6Oetqnq8fiesXQQmCBIH\nw26CKf/T9O1ZntfX4m4xr3LzdQs7wMr8g9zw+Ae+KvBfHD3BX1ZtZ9HKQg5VVnNh/2TumHgeIzK6\nalH3m9fvhLwnv3psgl89bkqBj4G8vl5QtZhXufm6hb2x5bFm76FK/uufWxj70DIefXcbozO78crs\nsTx960hG9uumhd2P1i46veWNiYG8vh65W8yr3LxfFR08xoL38vl7XqhFwFXn9mZWdiZnnuFSiwBl\nLxM8veWNiYG8vhZ3i3mVm/ebbXsPMz83n1c27CJOhKnDU5k5PpO0bi7fSarsJXH1F3Jp4qdexUBe\nX0/LWMyr3PzYzPrb0ja03FabisuZ+fRaLn1kOW9s3sPNY9JZfvdE/vtbg7WwtzTDbjq95Y2Jgby+\nHrlbzKvc/LO3jY7ptMyaggPMzc1n+eeldEyM598mZnHT2Ay6RrJFgLLbyYumbqVlYiCv32jOXUQS\ngeVAG0K/DF40xvyyzjoC/AmYDBwDbjLGrDvVdjXnrtxkjCH381Lm5QT4aPsXJLdvza3j+nHjqDQ6\nJCZ4PTylXONmzv04cJEx5oiIJAArROQNY8zqWutcDvQPf40E5oe/+4bTfLjt/c2d9n2PlfnW1Bje\n/GQPc3MCfLLrEL07JXL/VQO5fngfklrHuZ9FdpqVdvt1bd+el5zOxU9zdqDR4m5Ch/ZHwg8Twl91\nD/evBp4Kr7taRDqLSC9jzG5XR+sRp/lw2/ubO+37HgvzrQrW8Mr6XczPDZBfepSM5Hb8buoQrhma\nQuv48KUkt7PITrPSbr+u7dvzktO5+GnODjm6oCoicSKyHtgHvG2MWVNnlRSg9qXj4vAyX3CaD7e9\nv7nTvu82z7eyKsjTH2wn++Fcfvb3DbSOj2POd8/jnTsncP3wPl8VdnA/i+w0K+3269q+PS85nYuf\n5uyQowuqxpggMFREOgMvi8ggY8zm030xEZkBzABIS0s73X/uGaf5cNtz5E77vts43yPHq3l29Q6e\nWFFI6eHjnJ/WmV9fM5CJA3o0fNOR21lkp1lpt1/X9u15yelc/DRnh04rCmmMKQNygMvqPFUC1O4v\nmxpeVvffLzTGDDfGDO/evfvpjtUzDeXA6y53up5XGurvXne5TfMtO3aCR975nLEPLuO3b3zKgDM6\n8NxtI/nHrDFcdNYZp76btKHMcVOzyA1lousud/t1bd+el5zOxU9zdqjR4i4i3cNH7IhIEnAJ8Gmd\n1V4Fvi8ho4Byv5xvB+f5cNv7mzvt+27DfPcdruS3S7cy9sFlPPLONkZkdOXl28fwzA9GMiYz2VmL\nALezyE6z0m6/ru3b85LTufhpzg45OS3TC/iriMQR+mXwgjHmdRGZCWCMWQAsJRSDDBCKQt4cofF6\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x11863b470>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x_ponits = np.arange(4, 8)\n",
    "y_ = -(lr_clf.weights[1]*x_ponits + lr_clf.weights[0])/lr_clf.weights[2]\n",
    "plt.plot(x_ponits, y_)\n",
    "\n",
    "#lr_clf.show_graph()\n",
    "plt.scatter(X[:50,0],X[:50,1], label='0')\n",
    "plt.scatter(X[50:,0],X[50:,1], label='1')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "进入data_matrix函数。这里在每个x的属性之前都加了一个1，表示x_0，代表截距b。其中`*d`加了星号，其用法是把d中的数据解压，消除了array性质的影响。Another usage of the `*l` idiom is to unpack argument lists when calling a function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def data_matrix(X):\n",
    "    data_mat = []\n",
    "    for d in X:\n",
    "        data_mat.append([1.0, *d])\n",
    "    return data_mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1.0, 5.0999999999999996, 3.5],\n",
       " [1.0, 4.9000000000000004, 3.0],\n",
       " [1.0, 4.7000000000000002, 3.2000000000000002],\n",
       " [1.0, 4.5999999999999996, 3.1000000000000001],\n",
       " [1.0, 5.0, 3.6000000000000001],\n",
       " [1.0, 5.4000000000000004, 3.8999999999999999],\n",
       " [1.0, 4.5999999999999996, 3.3999999999999999],\n",
       " [1.0, 5.0, 3.3999999999999999],\n",
       " [1.0, 4.4000000000000004, 2.8999999999999999],\n",
       " [1.0, 4.9000000000000004, 3.1000000000000001]]"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_mat = data_matrix(X)\n",
    "data_mat[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 5.1,  3.5],\n",
       "       [ 4.9,  3. ],\n",
       "       [ 4.7,  3.2],\n",
       "       [ 4.6,  3.1],\n",
       "       [ 5. ,  3.6],\n",
       "       [ 5.4,  3.9],\n",
       "       [ 4.6,  3.4],\n",
       "       [ 5. ,  3.4],\n",
       "       [ 4.4,  2.9],\n",
       "       [ 4.9,  3.1]])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data_mat[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 1)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(len(data_mat[0]),1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "weights = np.zeros((len(data_mat[0]),1), dtype=np.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.],\n",
       "       [ 0.],\n",
       "       [ 0.]], dtype=float32)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "进入fit函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def sigmoid(x):\n",
    "        return 1 / (1 + exp(-x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "max_iter = 200\n",
    "learning_rate = 0.01"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LogisticRegression Model(learning_rate=0.01,max_iter=200)\n"
     ]
    }
   ],
   "source": [
    "for iter_ in range(max_iter):\n",
    "    for i in range(len(X)):\n",
    "        result = sigmoid(np.dot(data_mat[i], weights))\n",
    "        error = y[i] - result \n",
    "        weights += learning_rate * error * np.transpose([data_mat[i]])\n",
    "print('LogisticRegression Model(learning_rate={},max_iter={})'.format(learning_rate, max_iter))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "dot是正规的矩阵乘法，而普通的`*`则是点对点乘法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[37, 40],\n",
       "       [85, 92]])"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([[1,2],[3,4]]) \n",
    "b = np.array([[11,12],[13,14]]) \n",
    "np.dot(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[11, 24],\n",
       "       [39, 56]])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a * b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(data_mat[0], weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1.0, 4.7000000000000002, 3.2000000000000002]"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_mat[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1. ,  4.7,  3.2])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.transpose(data_mat[2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3,)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.transpose(data_mat[2]).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在`data_mat[2]`外面又套了一层`[]`，使其shape变为`[[1.0, 4.7, 3.2]]`，然后再进行转置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1. ],\n",
       "       [ 4.7],\n",
       "       [ 3.2]])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.transpose([data_mat[2]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.15475583],\n",
       "       [ 3.90847349],\n",
       "       [-6.28261614]], dtype=float32)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "进入score函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def score(self, X_test, y_test):\n",
    "    right = 0\n",
    "    X_test = self.data_matrix(X_test)\n",
    "    for x, y in zip(X_test, y_test):\n",
    "        result = np.dot(x, self.weights)\n",
    "        if (result > 0 and y == 1) or (result < 0 and y == 0):\n",
    "            right += 1\n",
    "    return right / len(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1.0, 4.7999999999999998, 3.1000000000000001],\n",
       " [1.0, 5.7000000000000002, 2.7999999999999998],\n",
       " [1.0, 4.9000000000000004, 3.1000000000000001],\n",
       " [1.0, 5.0, 3.6000000000000001],\n",
       " [1.0, 5.2000000000000002, 2.7000000000000002],\n",
       " [1.0, 6.7999999999999998, 2.7999999999999998],\n",
       " [1.0, 6.2000000000000002, 2.8999999999999999],\n",
       " [1.0, 4.2999999999999998, 3.0],\n",
       " [1.0, 6.0999999999999996, 3.0],\n",
       " [1.0, 4.4000000000000004, 3.2000000000000002]]"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test = data_matrix(X_test)\n",
    "X_test[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "y = np.dot(X_test[0], weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.8701931])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [py35]",
   "language": "python",
   "name": "Python [py35]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
